package com.zenithmind.document.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.document.mapper.DocumentCategoryMapper;
import com.zenithmind.document.pojo.domain.DocumentCategory;
import com.zenithmind.document.pojo.dto.DocumentCategoryCreateDTO;
import com.zenithmind.document.pojo.dto.DocumentCategoryUpdateDTO;
import com.zenithmind.document.pojo.query.DocumentCategoryQueryDTO;
import com.zenithmind.document.pojo.vo.DocumentCategoryVO;
import com.zenithmind.document.service.DocumentCategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文档分类服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DocumentCategoryServiceImpl extends ServiceImpl<DocumentCategoryMapper, DocumentCategory> implements DocumentCategoryService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DocumentCategoryVO createCategory(DocumentCategoryCreateDTO createDTO) {
        log.info("创建文档分类: {}", createDTO.getName());
        
        // 检查名称是否存在
        if (checkCategoryNameExists(createDTO.getName(), createDTO.getParentId(), null)) {
            throw new RuntimeException("分类名称已存在");
        }
        
        DocumentCategory category = new DocumentCategory();
        BeanUtils.copyProperties(createDTO, category);
        category.setCreatorId(UserContext.getUserId());
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        
        // 设置层级和路径
        if (createDTO.getParentId() != null) {
            DocumentCategory parent = getById(createDTO.getParentId());
            if (parent != null) {
                category.setLevel(parent.getLevel() + 1);
                category.setPath(parent.getPath() + "/" + category.getId());
            }
        } else {
            category.setLevel(1);
            category.setPath("/" + category.getId());
        }
        
        // 设置排序值
        if (category.getSortOrder() == null) {
            Integer maxSortOrder = baseMapper.getMaxSortOrder(createDTO.getParentId());
            category.setSortOrder(maxSortOrder + 1);
        }
        
        save(category);
        
        return convertToVO(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCategory(String id, DocumentCategoryUpdateDTO updateDTO) {
        log.info("更新文档分类: {}", id);
        
        DocumentCategory category = getById(id);
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }
        
        // 检查名称是否存在
        if (updateDTO.getName() != null && 
            checkCategoryNameExists(updateDTO.getName(), category.getParentId(), id)) {
            throw new RuntimeException("分类名称已存在");
        }
        
        BeanUtils.copyProperties(updateDTO, category);
        category.setUpdateTime(LocalDateTime.now());
        
        return updateById(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteCategory(String id) {
        log.info("删除文档分类: {}", id);
        
        // 检查是否可以删除
        if (!canDeleteCategory(id)) {
            throw new RuntimeException("分类下有子分类或文档，无法删除");
        }
        
        DocumentCategory category = getById(id);
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }
        
        category.setUpdateTime(LocalDateTime.now());
        
        return updateById(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteCategories(List<String> ids) {
        log.info("批量删除文档分类: {}", ids);
        
        for (String id : ids) {
            if (!canDeleteCategory(id)) {
                throw new RuntimeException("分类ID " + id + " 下有子分类或文档，无法删除");
            }
        }
        
        return removeBatchByIds(ids);
    }

    @Override
    public IPage<DocumentCategoryVO> getCategoryPage(DocumentCategoryQueryDTO queryDTO) {
        log.info("分页查询文档分类");
        
        Page<DocumentCategoryVO> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        
        return baseMapper.selectCategoryPageWithDetails(
                page,
                queryDTO.getKeyword(),
                queryDTO.getParentId(),
                queryDTO.getStatus()
        );
    }

    @Override
    public DocumentCategoryVO getCategoryDetail(String id) {
        log.info("获取文档分类详情: {}", id);
        
        DocumentCategory category = getById(id);
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }
        
        return convertToVO(category);
    }

    @Override
    public List<DocumentCategoryVO> getCategoryTree(String parentId, Boolean includeDisabled) {
        log.info("获取分类树: parentId={}, includeDisabled={}", parentId, includeDisabled);
        
        return baseMapper.selectCategoryTree(parentId, includeDisabled);
    }

    @Override
    public List<DocumentCategoryVO> getChildCategories(String parentId, Boolean includeDisabled) {
        log.info("获取子分类列表: parentId={}, includeDisabled={}", parentId, includeDisabled);
        
        return baseMapper.selectChildCategories(parentId, includeDisabled);
    }

    @Override
    public List<DocumentCategoryVO> getCategoryPath(String categoryId) {
        log.info("获取分类路径: categoryId={}", categoryId);
        
        return baseMapper.selectCategoryPath(categoryId);
    }

    @Override
    public List<DocumentCategoryVO> searchCategories(String keyword, Integer limit) {
        log.info("搜索分类: keyword={}", keyword);
        
        return baseMapper.searchCategories(keyword, limit);
    }

    @Override
    public List<DocumentCategoryVO> getHotCategories(Integer limit) {
        log.info("获取热门分类");
        
        return baseMapper.selectHotCategories(limit);
    }

    @Override
    public List<DocumentCategoryVO> getUserCategories(String creatorId, Integer limit) {
        log.info("获取用户创建的分类: creatorId={}", creatorId);
        
        return baseMapper.selectUserCategories(creatorId, limit);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean moveCategory(String categoryId, String newParentId) {
        log.info("移动分类: categoryId={}, newParentId={}", categoryId, newParentId);
        
        DocumentCategory category = getById(categoryId);
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }
        
        // 计算新的层级和路径
        Integer newLevel = 1;
        String newPath = "/" + categoryId;
        
        if (newParentId != null) {
            DocumentCategory parent = getById(newParentId);
            if (parent != null) {
                newLevel = parent.getLevel() + 1;
                newPath = parent.getPath() + "/" + categoryId;
            }
        }
        
        return baseMapper.moveCategory(categoryId, newParentId, newLevel, newPath) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean reorderCategories(List<String> categoryIds, String parentId) {
        log.info("调整分类排序: parentId={}", parentId);
        
        return baseMapper.batchUpdateCategoryOrder(categoryIds, parentId) > 0;
    }

    @Override
    public DocumentCategoryVO copyCategory(String sourceCategoryId, String newName, String parentId) {
        log.info("复制分类: sourceCategoryId={}, newName={}", sourceCategoryId, newName);
        
        String userId = UserContext.getUserId();
        String newCategoryId = baseMapper.copyCategory(sourceCategoryId, newName, parentId, userId);
        DocumentCategory newCategory = getById(newCategoryId);
        
        return convertToVO(newCategory);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCategoryDocumentCount(String categoryId) {
        log.info("更新分类文档数量: categoryId={}", categoryId);
        
        return baseMapper.updateCategoryDocumentCount(categoryId) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateCategoryDocumentCount(List<String> categoryIds) {
        log.info("批量更新分类文档数量: categoryIds={}", categoryIds);
        
        return baseMapper.batchUpdateCategoryDocumentCount(categoryIds) > 0;
    }

    @Override
    public DocumentCategoryVO getCategoryStatistics(String categoryId) {
        log.info("获取分类统计信息: categoryId={}", categoryId);
        
        return baseMapper.selectCategoryStatistics(categoryId);
    }

    @Override
    public Boolean checkCategoryNameExists(String name, String parentId, String excludeId) {
        log.info("检查分类名称是否存在: name={}, parentId={}", name, parentId);
        
        return baseMapper.checkCategoryNameExists(name, parentId, excludeId);
    }

    @Override
    public Boolean canDeleteCategory(String categoryId) {
        log.info("检查分类是否可以删除: categoryId={}", categoryId);
        
        // 检查是否有子分类
        if (baseMapper.hasChildCategories(categoryId)) {
            return false;
        }
        
        // 检查是否有文档
        if (baseMapper.hasDocuments(categoryId)) {
            return false;
        }
        
        return true;
    }

    /**
     * 转换为VO
     */
    private DocumentCategoryVO convertToVO(DocumentCategory category) {
        DocumentCategoryVO vo = new DocumentCategoryVO();
        BeanUtils.copyProperties(category, vo);
        
        // TODO: 补充其他字段转换
        
        return vo;
    }
}
